package component.group;

import java.util.HashSet;
import java.util.Set;

import component.AbstractComponent;
import component.traverse.*;

public class CanRemoveComponents implements TraverseListener {
	
	private final ComponentGroup group;
	private final Set<AbstractComponent> knownPathToRoot = new HashSet<AbstractComponent>();
	
	private ComponentGroup currentTraverse = null;
	private boolean rootFound = false;
	
	public CanRemoveComponents(ComponentGroup group) {
		this.group = group;
	}
	
	public boolean canRemove() {
		if (group.isLocked() || group.hasRoot())
			return false;
		else
			return checkAllComponents();
	}
	
	private boolean checkAllComponents() {
		for (AbstractComponent component : group.getComponents()) {
			if (!checkComponent(component)) return false;
		}
		return true;
	}

	private boolean checkComponent(AbstractComponent component) {
		if (component.isRoot()) return false;
		Traverse traverse;
		for (AbstractComponent child : component.getConnectedComponents()) {
			if (!group.contains(child) && !knownPathToRoot.contains(child)) {
				currentTraverse = new ComponentGroup();
				rootFound = false;
				
				traverse = new Traverse();
				traverse.setBorder(group);
				traverse.addListener(this);
				
				traverse.traverse(child, null);
				if (rootFound) {
					knownPathToRoot.addAll(currentTraverse.getComponents());
					currentTraverse.clear();
					currentTraverse = null;
				} else {
					return false;
				}
			}
		}
		
		return true;
	}

	@Override
	public boolean traverseNode(AbstractComponent component, Object command) {
		currentTraverse.add(component);
		if (component.isRoot() || knownPathToRoot.contains(component)) {
			rootFound = true;
			return false;
		}
		return true;
	}

}
